import yaml
import os
import threading
from types import SimpleNamespace

# 如需修改，请见62行

class ConfigLoadError(Exception):
    """自定义配置加载异常"""
    pass

class AppConfig:
    _instance = None
    _lock = threading.Lock()
    _initialized = False

    def __new__(cls, *args, **kwargs):
        with cls._lock:
            if not cls._instance:
                cls._instance = super().__new__(cls)
            return cls._instance

    def __init__(self, config_path="app_config.yaml"):
        if self._initialized:
            return

        self.config_path = config_path
        self._raw_config = None
        self.config = None
        
        try:
            self._load_config()
            self._validate_config()
            self._create_namespace()
            self._initialized = True
        except Exception as e:
            raise ConfigLoadError(f"配置文件加载失败: {str(e)}") from e

    def _load_config(self):
        """加载YAML配置文件"""
        if not os.path.exists(self.config_path):
            raise FileNotFoundError(f"配置文件 {self.config_path} 不存在")
            
        try:
            with open(self.config_path, 'r', encoding='utf-8') as f:
                self._raw_config = yaml.safe_load(f)
        except yaml.YAMLError as e:
            raise ValueError(f"YAML解析错误: {str(e)}")

    def _validate_config(self):
        """验证配置结构"""
        # required_sections = ['app', 'SQL_Config', 'log']
        # for section in required_sections:
        #     if section not in self._raw_config:
        #         raise ValueError(f"缺少必要配置段: {section}")
                
        # # 检查SQL密码字段拼写
        # sql_config = self._raw_config['SQL_Config']
        # if 'password' not in sql_config:
        #     raise ValueError("SQL配置缺少password字段")

    """
    如需修改配置文件结构，请在此函数中添加或删除相应的属性
    如果修改了配置文件结构，请确保在_create_namespace函数中更新相应的属性
    还要添加相应的访问方法，如get_app_status等
    """
    def _create_namespace(self):
        """将配置转换为命名空间对象"""
        self.config = SimpleNamespace(
            app=SimpleNamespace(**self._raw_config['app']),
            log=SimpleNamespace(**self._raw_config['log']),
            display=SimpleNamespace(**self._raw_config['display']),
            train=SimpleNamespace(**self._raw_config['train'])
        )
        

    @property
    def app(self):
        """获取应用状态"""
        return self.config.app

    @property
    def log_dir(self):
        """获取日志目录"""
        return self.config.log.log_file_dir

    @property
    def display(self):
        """获取Web服务器配置信息"""
        return self.config.display
    
    @property
    def train(self):
        """获取训练配置信息"""
        return self.config.train
    
# 创建全局单例实例
app_config = AppConfig()

# 使用示例
if __name__ == "__main__":
    try:
        # 测试单例模式
        config1 = AppConfig()
        config2 = AppConfig()
        
        print(f"是否同一个实例: {config1 is config2}")  # 输出 True
        
        print("应用状态:", config1.app_status)
        print("数据库配置:", config1.db_connection_params)
        print("日志目录:", config1.log_dir)
        
    except ConfigLoadError as e:
        print(f"配置加载错误: {str(e)}")
    except Exception as e:
        print(f"未知错误: {str(e)}")